using Excel;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;

namespace Super
{
	public static class ExcelUtil
	{
		/// <summary>
		/// 获取表格基本信息
		/// </summary>
		/// <param name="excelPath">表格路径</param>
		/// <param name="sheetIndex">第几张表   从0开始</param>
		/// <returns></returns>
		public static ExcelTableInfo GetTableInfo(string excelPath, int sheetIndex)
		{
			string excelAbsolutePath = GlobalUtil.GetAbsolutePath(excelPath);
			ExcelTableInfo tableInfo = GetExcelTableData(excelPath, sheetIndex);
			string tableName = GetExcelTableNames(excelAbsolutePath)[sheetIndex];
			tableInfo.hasKey = false;
			tableInfo.hasLang = false;
			tableInfo.fieldNum = tableInfo.col - tableInfo.ignoreCol;
			tableInfo.remarks = FormatRemarks(tableInfo.data[0].Skip(tableInfo.ignoreCol).ToArray());
			tableInfo.fieldNames = tableInfo.data[1].Skip(tableInfo.ignoreCol).ToArray();
			tableInfo.fieldTypes = GetExcelFieldTypes(tableInfo);
			tableInfo.nodeName = tableName + "Node";
			tableInfo.tableName = tableName + "Table";
			tableInfo.tablePath = string.Format(FWConfig.excelTablePath, tableInfo.tableName);

			HandleSpecialField(tableInfo);

			return tableInfo;
		}

		/// <summary>
		/// 获取Excel所有表的名称
		/// </summary>
		/// <param name="path">Excel的文件路径</param>
		/// <returns></returns>
		public static List<string> GetExcelTableNames(string path)
		{
			path = GlobalUtil.GetAbsolutePath(path);
			FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
			IExcelDataReader excelRead = ExcelReaderFactory.CreateOpenXmlReader(stream);
			DataSet result = excelRead.AsDataSet();
			List<string> names = new List<string>();
			for (int i = 0; i < result.Tables.Count; i++)
			{
				names.Add(result.Tables[i].TableName);
			}
			return names;
		}
		
		/// <summary>
		/// 格式化备注内容
		/// </summary>
		/// <param name="remarksArg"></param>
		/// <returns></returns>
		public static string[] FormatRemarks(string[] remarksArg)
		{
			string[] remarks = new string[remarksArg.Length];
			for (int i = 0; i < remarksArg.Length; i++)
			{
				
				remarks[i] = remarksArg[i].Replace("\n", "|");
			}
			return remarks;
		}
		
		private static ExcelTableInfo GetExcelTableData(string path, int sheetIndex)
		{
			FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
			IExcelDataReader excelRead = ExcelReaderFactory.CreateOpenXmlReader(stream);
			DataSet result = excelRead.AsDataSet();
			DataRowCollection collect = result.Tables[sheetIndex].Rows;
			int col = result.Tables[sheetIndex].Columns.Count;
			int row = result.Tables[sheetIndex].Rows.Count;
			int offsetCol = 1;
			int offsetRow = 2;
			string[][] data;
			while (row > 0)
			{
				if (collect[row - 1][offsetCol].ToString() == "")
				{
					row--;
					continue;
				}
				break;
			}
			while (col > 0)
			{
				if (collect[offsetRow][col - 1].ToString() == "")
				{
					col--;
					continue;
				}
				break;
			}

			data = new string[row][];
			for (int i = 0; i < row; i++)
			{
				data[i] = new string[col];
				for (int j = 0; j < col; j++)
				{
					data[i][j] = collect[i][j].ToString();
				}
			}
			ExcelTableInfo info = new ExcelTableInfo();
			info.data = data;
			info.row = row;
			info.col = col;
			info.ignoreRow = 3;
			info.ignoreCol = offsetCol;
			return info;
		}

		private static string[] GetExcelFieldTypes(ExcelTableInfo tableInfo)
		{
			string[] res = tableInfo.data[2].Skip(tableInfo.ignoreCol).ToArray();
			for (int i = 0; i < res.Length; i++)
			{
				if (res[i].StartsWith("enum"))
				{
					res[i] = res[i].Replace("enum", "");
				}
			}
			return res;
		}

		private static void HandleSpecialField(ExcelTableInfo tableInfo)
		{
			for (int i = tableInfo.ignoreCol; i < tableInfo.fieldNum + tableInfo.ignoreCol; i++)
			{
				string fieldName = tableInfo.data[1][i];
				bool isKey = false, isLang = false;
				if (fieldName.Contains("[K]") || fieldName.Contains("[k]"))
				{
					isKey = true;
					tableInfo.hasKey = true;
					fieldName = fieldName.Replace("[K]", "");
					fieldName = fieldName.Replace("[k]", "");
				}

				if (fieldName.Contains("[L]") || fieldName.Contains("[l]"))
				{
					isLang = true;
					tableInfo.hasLang = true;
					fieldName = fieldName.Replace("[L]", "");
					fieldName = fieldName.Replace("[l]", "");
				}

				if (isKey)
				{
					tableInfo.keys.Add(fieldName);
					tableInfo.keyTypes.Add(tableInfo.data[2][i]);
				}

				if (isLang)
				{
					tableInfo.langFieldNames.Add(fieldName);
					tableInfo.langFieldIndexs.Add(i - tableInfo.ignoreCol);
				}
				tableInfo.fieldNames[i - tableInfo.ignoreCol] = fieldName;
			}
		}
	}

}
